﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Documents;
using System.Collections.ObjectModel;
using System.Windows.Controls;
using System.Windows;
using SmartPaginator.Extensions;

namespace SmartPaginator.Elements
{
    public class FigureElement: BlockContainerElement
    {
        #region Constructor

        protected FigureElement(Figure source):base(source)
        {
            this.Background = source.Background;
            this.Margin = CalculateMargin();
            this.Padding = CalculatePadding();
        }

        public FigureElement(Figure source, IElementFactory factory)
            : base(source, source.Blocks, factory)
        {
            this.Background = source.Background;
            this.Margin = CalculateMargin();
            this.Padding = CalculatePadding();
        }

        #endregion

        #region Properties

        public Figure Figure { get { return Source as Figure; } }

        #endregion

        #region GetEmptyCopy Method

        public override IBlockElement GetEmptyCopy()
        {
            var result = new FigureElement(this.Figure);
            result.Height = this.Height;
            result.Width = this.Width;
            result.Margin = this.Margin;
            result.Padding = this.Padding;
            return result;
        }

        #endregion

        #region GetCopy Method

        public FigureElement GetCopy()
        {
            var context = new HarvestingContext();
            var result = this.Harvest(context, double.PositiveInfinity, null);
            var copy = result.HarvestedElement as FigureElement;
            Canvas.SetLeft(copy, Canvas.GetLeft(this));
            Canvas.SetTop(copy, Canvas.GetTop(this));
            copy.Margin = this.Margin;
            return copy;
        }

        #endregion

        #region CalculateMargin and CalculatePadding Methods

        private Thickness CalculateMargin()
        {
            var result = new Thickness();
            if (Figure != null)
            {
                result.Left = CalculateMargin(Figure.Margin.Left);
                result.Top = CalculateMargin(Figure.Margin.Top);
                result.Right = CalculateMargin(Figure.Margin.Right);
                result.Bottom = CalculateMargin(Figure.Margin.Bottom);
            }
            return result;
        }

        private double CalculateMargin(double sourceValue)
        {
            if (double.IsNaN(sourceValue) || double.IsInfinity(sourceValue))
                return Figure.GetLineHeight() * 0.5;

            return sourceValue;
        }

        private Thickness CalculatePadding()
        {
            var result = new Thickness();
            if (Figure != null)
            {
                result.Left = CalculatePadding(Figure.Margin.Left);
                result.Top = CalculatePadding(Figure.Margin.Top);
                result.Right = CalculatePadding(Figure.Margin.Right);
                result.Bottom = CalculatePadding(Figure.Margin.Bottom);
            }
            return result;
        }


        private double CalculatePadding(double sourceValue)
        {
            if (double.IsNaN(sourceValue) || double.IsInfinity(sourceValue))
                return Figure.GetLineHeight() * 0.5;

            return sourceValue;
        }

        #endregion

        #region GetBounds Method

        public Rect GetBounds()
        {
            var location = new Point(Canvas.GetLeft(this), Canvas.GetTop(this));
            var size = new Size(this.Width + this.Margin.Left + this.Margin.Right,
                                this.Height + this.Margin.Top + this.Margin.Bottom);
            return new Rect(location, size);
        }

        #endregion

    }
}
